const path = require("path");
const fs = require("fs");
const jwt = require("jsonwebtoken");
const { Result } = require('@/libs/result');
const keyPath = path.join("./app/src/secret-key", "jwt.key");
const secretKey = fs.readFileSync(keyPath, "utf8");
const redisClient = require("@/redis/redis-client");
const RedisKeysConstant = require("../constants/redis-keys.constant");
const { TenantContext } = require('@/core/tenant-context');


/**
 * 租户中间件
 * @param {*} ctx
 * @param {*} next
 * @returns
 */
async function tenantsMiddleware(ctx, next) {
    const tenantId = ctx.request.get("t_id"); // 租户
	const url = ctx.request.url;
    const throwError = () => {
        ctx.status = 401;
        ctx.body = Result.Failed("认证失败");
    }
    const _checkWhitePath = (path) => {
        const API_PREFIX = '/api/v1'
        const WhiteList = ["/auth/login", '/auth/wechat_login', '/file/preview/*', '/app/uploads/*/*'].map(path => `${API_PREFIX}${path}`); // 白名单
        if (WhiteList.includes(path)) {
            return true;
        }
        const diffParamPath = (path, diffValue) => {
            const pathArr = path.split('/');
            const valueArr = diffValue.split('/');
            if (pathArr.length !== valueArr.length) return false;
            for (let i = 0; i < pathArr.length; i++) {
                if (pathArr[i] !== "*") {
                    if (valueArr[i] !== pathArr[i]) {
                        return false;
                    }
                }
            }
            return true;
        }
        for (let i = 0; i < WhiteList.length; i++) {
            if (path === WhiteList[i]) {
                return true;
            }
            // 如果是带参数路径，走带参数的验证
            if (WhiteList[i].indexOf('*') > -1) {
                if (diffParamPath(WhiteList[i], path)) {
                    return true;
                }
            }
        }
        return false;
    }
	if (_checkWhitePath(url)) {
		await next();
		return;
	}
	try {
		ctx.state.tid = tenantId; // 将租户id存储在 ctx.state 上，以便后续中间件或路由使用
        // 将租户、用户挂载到租户上下文中，方便其他地方读取；
        TenantContext.setCurrentTenant(tenantId);
        TenantContext.setCurrentUser(ctx.state.user.uid);
		await next();
    } catch (error) {
        console.log("tenantsMiddleware:", error);
		throwError()
	}
}

module.exports = tenantsMiddleware;
